package com.wufun.overseas.main.activity;

import android.Manifest;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.ServiceConnection;
import android.content.pm.ActivityInfo;
import android.content.pm.PackageManager;
import android.content.res.AssetFileDescriptor;
import android.graphics.Bitmap;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.wifi.WifiManager;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.Parcelable;
import android.os.Vibrator;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.util.Log;
import android.view.KeyEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

import com.google.zxing.BarcodeFormat;
import com.google.zxing.Result;
import com.wufun.baselibrary.utils.LogUtils;
import com.wufun.overseas.R;
import com.wufun.overseas.common.SocketStatusEvent;
import com.wufun.overseas.main.base.MyActivity;
import com.wufun.overseas.main.service.SocketClientService;
import com.wufun.overseas.tools.filetransfer.ApWifiManager;
import com.wufun.overseas.tools.filetransfer.ApWifiUtil;
import com.wufun.overseas.tools.filetransfer.WifiUtils;
import com.wufun.overseas.tools.socket.entity.SocketConfig;
import com.wufun.overseas.zxing.v2.camera.CameraManager;
import com.wufun.overseas.zxing.v2.decoding.CaptureActivityHandlerForFace;
import com.wufun.overseas.zxing.v2.decoding.InactivityTimer;
import com.wufun.overseas.zxing.v2.view.ViewfinderView;

import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;

import java.io.IOException;
import java.util.Date;
import java.util.Vector;

import butterknife.Bind;
import butterknife.ButterKnife;

/**
 * Author: hest
 * Date:  2016/4/15
 * 面传中二维码扫描界面
 */

public class FaceTransferScanQrCodeActivity extends MyActivity implements SurfaceHolder.Callback {

    private static final String TAG = FaceTransferScanQrCodeActivity.class.getSimpleName();
    @Bind(R.id.preview_view)
    SurfaceView previewView;
    @Bind(R.id.viewfinder_view)
    ViewfinderView viewfinderView;
    @Bind(R.id.scan_qr_code_fl)
    FrameLayout scanQrCodeFl;

    private CaptureActivityHandlerForFace handler;
    private TextView title_txt;
    private ImageView back_img;
    private boolean hasSurface;
    private Vector<BarcodeFormat> decodeFormats;
    private String characterSet;
    private InactivityTimer inactivityTimer;
    private MediaPlayer mediaPlayer;
    private boolean playBeep;
    private static final float BEEP_VOLUME = 0.10f;
    final public static int REQUEST_CODE_ASK_CAMERA = 123;
    private boolean vibrate;
    Context context;
    ApWifiManager apWifiManager;
    WifiUtils wifiUtil = null;
    ApWifiUtil mApWifiUtil = null;
    SurfaceView surfaceView;
    String SSID = null;
    String PWD = null;
    NetWorkConnectedReceiver receiver = null;
    boolean openWifi = false;
    boolean hasConnectedWifi = false;
    boolean serviceBound = false;
    CameraManager cameraManager;

    private long startTime, endTime;
    private long outTime = 5000;

    /**
     * Called when the activity is first created.
     */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        cameraManager = new CameraManager(this);
        setContentView(R.layout.face_transfer_scan_qr_code_activity);
        ButterKnife.bind(this);

        context = getApplicationContext();
        apWifiManager = new ApWifiManager(context);
        wifiUtil = WifiUtils.getInstance(context);
        mApWifiUtil = ApWifiUtil.getInstance(context);

        initView();
        getPermission();
    }

    private void initView() {
        getBarBackLl().setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                FaceTransferScanQrCodeActivity.this.finish();
            }
        });
        setBarTitleTx(R.string.title_scan_qr_code);
        hasSurface = false;
        inactivityTimer = new InactivityTimer(this);
    }

    /*******************************Permission********************************/
    private void getPermission() {
        int hasWriteContactsPermission = ContextCompat.checkSelfPermission(this,
                Manifest.permission.CAMERA);
        if (hasWriteContactsPermission != PackageManager.PERMISSION_GRANTED) {

            ActivityCompat.requestPermissions(this,
                    new String[]{Manifest.permission.CAMERA},
                    REQUEST_CODE_ASK_CAMERA);
            return;
        }
        startCameral();
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
        switch (requestCode) {
            case REQUEST_CODE_ASK_CAMERA:
                if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    // Permission Granted
                    startCameral();
                } else {
                    //如果app之前请求过该权限,被用户拒绝, 这个方法就会返回true.
                    //如果用户之前拒绝权限的时候勾选了对话框中”Don’t ask again”的选项,那么这个方法会返回false.
                    //       如果设备策略禁止应用拥有这条权限, 这个方法也返回false.
                    if (!ActivityCompat.shouldShowRequestPermissionRationale(this,
                            Manifest.permission.CAMERA)) {
                        Toast.makeText(this, "扫描二维码需要相机权限,请授权相机权限", Toast.LENGTH_SHORT)
                                .show();
                        return;
                    }
                    // Permission Denied
                    Toast.makeText(this, "没有获取到权限,请授权相机权限", Toast.LENGTH_SHORT)
                            .show();
                }
                break;
            default:
                super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        }
    }

    /*******************************Permission********************************/

    @Override
    protected void onResume() {
        super.onResume();
        if (getRequestedOrientation() != ActivityInfo.SCREEN_ORIENTATION_PORTRAIT) {
            setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
        }
        // CameraManager.init(getApplication());
        cameraManager = new CameraManager(getApplication());

        viewfinderView.setCameraManager(cameraManager);

        SurfaceHolder surfaceHolder = surfaceView.getHolder();
        if (hasSurface) {
            initCamera(surfaceHolder);
        } else {
            surfaceHolder.addCallback(this);
            surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
        }
        decodeFormats = null;
        characterSet = null;

        playBeep = true;
        AudioManager audioService = (AudioManager) getSystemService(AUDIO_SERVICE);
        if (audioService.getRingerMode() != AudioManager.RINGER_MODE_NORMAL) {
            playBeep = false;
        }
        initBeepSound();
        vibrate = true;
    }

    //开启扫描
    private void startCameral() {
        surfaceView = (SurfaceView) findViewById(R.id.preview_view);
        SurfaceHolder surfaceHolder = surfaceView.getHolder();
        if (hasSurface) {
            initCamera(surfaceHolder);
        } else {
            surfaceHolder.addCallback(this);
            surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
        }
        decodeFormats = null;
        characterSet = null;

        playBeep = true;
        AudioManager audioService = (AudioManager) getSystemService(AUDIO_SERVICE);
        if (audioService.getRingerMode() != AudioManager.RINGER_MODE_NORMAL) {
            playBeep = false;
        }
        initBeepSound();
        vibrate = true;
    }

    @Override
    protected void onPause() {
        super.onPause();
        if (handler != null) {
            handler.quitSynchronously();
            handler = null;
        }
        cameraManager.closeDriver();
    }

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if (keyCode == KeyEvent.KEYCODE_BACK) {
            stopService();
            finish();
        }
        return super.onKeyDown(keyCode, event);
    }

    @Override
    protected void onDestroy() {
        inactivityTimer.shutdown();
        stopService();
        unRegistWifiConnected();
        super.onDestroy();
    }


    /**
     * 处理扫描结果
     *
     * @param result
     * @param barcode
     */
    public void handleDecode(Result result, Bitmap barcode) {
        inactivityTimer.onActivity();
        playBeepSoundAndVibrate();
        String resultString = result.getText();
        Log.d(TAG, "handleDecode: 扫描结果" + resultString);
        if (resultString.equals("")) {
            showToast("Scan failed!");
        } else {
            String[] apWifiInfo = resultString.split(":");
            int size = apWifiInfo.length;
            Log.d(TAG, "handleDecode: 扫描结果::::" + apWifiInfo.toString() + ":::::size::::" + size);
            if (size == 4) {
                SSID = apWifiInfo[1];
                PWD = apWifiInfo[3];
                if (!wifiUtil.isWifiEnable()) {
                    openWifi = true;
                    mApWifiUtil.closeWifiAp();
                    wifiUtil.openWifi(context);
                } else {
                    connectApWifi();
                }
                surfaceView.setVisibility(View.GONE);
                viewfinderView.setVisibility(View.GONE);
                registWifiConnected();
            } else {
                showToast(getResources().getString(R.string.erro_scan_qr_code));
            }
        }
    }

    //连接wifi
    private void connectApWifi() {
        boolean b = apWifiManager.connectApWifi(SSID, PWD);
        LogUtils.e(">>>>>>>>>tbl:"+b+",SSID:"+SSID+",PWD:"+PWD);
    }

    //文件传输界面
    private void goGameTransfer() {
        Log.d(TAG, "run: 跳转到面传界面");
        cancelLoading();
        startActivity(GameTransferActivity.buildIntent(mContext, SocketConfig.SOCKET_CLIENT_FLAG));
        finish();
    }

    private void connected2Service() {
        Intent intent = new Intent(FaceTransferScanQrCodeActivity.this, SocketClientService.class);
        String localIp = wifiUtil.getLocalIPAddress();
        int lastPointIndex = localIp.lastIndexOf(".");
        String host = localIp.substring(0, lastPointIndex) + ".1";
        Log.d(TAG, "connected2Service: host" + host + ":::本地地址:::" + localIp);
        intent.putExtra("host", host);
        this.bindService(intent, connection, Context.BIND_AUTO_CREATE);
        this.startService(intent);
        serviceBound = true;
    }

    void stopService() {
        if (serviceBound) {
            unbindService(connection);
            Intent intent = new Intent(FaceTransferScanQrCodeActivity.this, SocketClientService.class);
            stopService(intent);
        }
    }


    SocketClientService.SocketBinder mBinder = null;
    ServiceConnection connection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
            if (iBinder instanceof SocketClientService.SocketBinder) {
                mBinder = (SocketClientService.SocketBinder) iBinder;
                mBinder.newSocket();
            }
        }

        @Override
        public void onServiceDisconnected(ComponentName componentName) {
        }
    };


    //Socket 连接状态
    @Subscribe(threadMode = ThreadMode.MAIN)
    public void onSocketStatusEvent(SocketStatusEvent bean) {
        LogUtils.e(TAG + "onSocketStatusEvent: 0000");
        if (bean == null) {
            return;
        }
        LogUtils.e(TAG + "onSocketStatusEvent: 11111");
        switch (bean.status) {
            case SocketStatusEvent.CONNECTED_SUCCESS:
                LogUtils.e(TAG + "onSocketStatusEvent: 成功");

                goGameTransfer();
                break;
            case SocketStatusEvent.CONNECTED_FAILED:
                stopService();
                finish();
                break;
            default:
                break;
        }
    }

    private void initCamera(SurfaceHolder surfaceHolder) {
        try {
            // CameraManager.get().openDriver(surfaceHolder);
            cameraManager.openDriver(surfaceHolder);
        } catch (IOException ioe) {
            return;
        } catch (RuntimeException e) {
            return;
        }
        if (handler == null) {
            handler = new CaptureActivityHandlerForFace(this, decodeFormats, characterSet);
        }
    }

    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {

    }

    @Override
    public void surfaceCreated(SurfaceHolder holder) {
        if (!hasSurface) {
            hasSurface = true;
            initCamera(holder);
        }

    }

    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {
        hasSurface = false;

    }

    public ViewfinderView getViewfinderView() {
        return viewfinderView;
    }

    public Handler getHandler() {
        return handler;
    }

    public void drawViewfinder() {
        viewfinderView.drawViewfinder();

    }

    private void initBeepSound() {
        if (playBeep && mediaPlayer == null) {
            setVolumeControlStream(AudioManager.STREAM_MUSIC);
            mediaPlayer = new MediaPlayer();
            mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
            mediaPlayer.setOnCompletionListener(beepListener);

            AssetFileDescriptor file = getResources().openRawResourceFd(
                    R.raw.jiejitoubi);
            try {
                mediaPlayer.setDataSource(file.getFileDescriptor(),
                        file.getStartOffset(), file.getLength());
                file.close();
                mediaPlayer.setVolume(BEEP_VOLUME, BEEP_VOLUME);
                mediaPlayer.prepare();
            } catch (IOException e) {
                mediaPlayer = null;
            }
        }
    }

    private static final long VIBRATE_DURATION = 200L;

    private void playBeepSoundAndVibrate() {
        if (playBeep && mediaPlayer != null) {
            mediaPlayer.start();
        }
        if (vibrate) {
            Vibrator vibrator = (Vibrator) getSystemService(VIBRATOR_SERVICE);
            vibrator.vibrate(VIBRATE_DURATION);
        }
    }

    /**
     * When the beep has finished playing, rewind to queue up another one.
     */
    private final MediaPlayer.OnCompletionListener beepListener = new MediaPlayer.OnCompletionListener() {
        public void onCompletion(MediaPlayer mediaPlayer) {
            mediaPlayer.seekTo(0);
        }
    };


    void registWifiConnected() {
        IntentFilter filter = new IntentFilter();
        filter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION);
        filter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION);
        //这个监听网络连接的设置，包括wifi和移动数据的打开和关闭。.
        filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
        receiver = new NetWorkConnectedReceiver();
        registerReceiver(receiver, filter);
        startTime = System.currentTimeMillis();
        showLoading(getResources().getString(R.string.connecting_str), false);
    }

    void unRegistWifiConnected() {
        if (receiver != null) {
            unregisterReceiver(receiver);
        }
    }

    class NetWorkConnectedReceiver extends BroadcastReceiver {
        @Override
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            if (WifiManager.WIFI_STATE_CHANGED_ACTION.equals(action)) {//监听wifi 打开关闭
                int wifiState = intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE, 0);
                switch (wifiState) {
                    case WifiManager.WIFI_STATE_DISABLED://wifi 关闭
                        Log.d(TAG, "onReceive: wifi 关闭");
                        break;
                    case WifiManager.WIFI_STATE_DISABLING:
                        break;
                    case WifiManager.WIFI_STATE_ENABLED://wifi 打开
                        Log.d(TAG, "onReceive: wifi 打开");
                        if (openWifi) {
                            connectApWifi();
                        }
                        break;
                    case WifiManager.WIFI_STATE_ENABLING:
                        break;
                    case WifiManager.WIFI_STATE_UNKNOWN:
                        break;
                }
            }

            if (WifiManager.NETWORK_STATE_CHANGED_ACTION.equals(action)) {//wifi 连接状态
                Parcelable parcelableExtra = intent.getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO);
                if (null != parcelableExtra) {
                    NetworkInfo networkInfo = (NetworkInfo) parcelableExtra;
                    NetworkInfo.State state = networkInfo.getState();
                    endTime = System.currentTimeMillis();
                    switch (state) {
                        case CONNECTED://连接
                            String ssid = WifiUtils.getInstance(context).getSSID(context);
                            Log.d(TAG, "onReceive: wifi 连接上的名称" + ssid);
                            if (ssid != null && ssid.equals(SSID)) {
                                if (!hasConnectedWifi) {
                                    connected2Service();
                                    hasConnectedWifi = true;
                                }
                            }
                            break;
                        case UNKNOWN:
                            cancelLoading();
                            connectHotspotFailed();
                            break;
                        case CONNECTING:
                            if (twoTimeDis(startTime, endTime) >= outTime) {
                                cancelLoading();
                                connectHotspotFailed();
                            }
                            break;
                        case DISCONNECTED://断开连接
                            if (twoTimeDis(startTime, endTime) >= outTime) {
                                cancelLoading();
                                connectHotspotFailed();
                            }
                            break;
                        case DISCONNECTING:
                            break;
                        case SUSPENDED:
                            break;
                        default:
                            break;
                    }
                } else {
                    cancelLoading();
                    connectHotspotFailed();
                }
            }
        }
    }

    private void connectHotspotFailed () {
        showToast(getResources().getString(R.string.erro_scan_qr_str));
        finish();
    }

    private long twoTimeDis (long startTime, long endTime) {
        Date curDate = new Date(startTime);
        Date endDate = new Date(endTime);
        long diff = endDate.getTime() - curDate.getTime();
        return diff;
    }

    public CameraManager getCameraManager() {
        return cameraManager;
    }

}
